package com.opengroupe.resources;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.opengroupe.dto.CategorieDto;
import com.opengroupe.dto.QuestionDto;
import com.opengroupe.entities.Categorie;
import com.opengroupe.entities.Question;
import com.opengroupe.entities.Reponse;
import com.opengroupe.service.common.CrudService;
import com.opengroupe.service.pc.PCService;
import com.opengroupe.util.QrhUtil;
import com.opengroupe.utils.QrhWsUtils;

@Service("questionResource")
@Path("/question")
public class QuestionResource {
	
	@Autowired
	private QrhWsUtils utils;
	
	@Autowired
	private PCService pcService;
	
	@Autowired
	private CrudService crudService;
	
	private Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();

	@GET
	@Produces("application/json")
	@Path("/getAll")
	@Transactional
	public String allQuestions() {
		@SuppressWarnings("unchecked")
		List<Question> questions = (List<Question>) crudService.read(Question.class.getCanonicalName());
		
		List<QuestionDto> questionDtos = new ArrayList<QuestionDto>();
		for(Question question : questions){
			questionDtos.add(QrhWsUtils.convertQuestionToQuestionDto(question));
		}
		
		return gson.toJson(questionDtos);
	}
	
	@DELETE
	@Path("/delete")
	public void deleteQuestion(String idQuestion) {
		pcService.deleteQuestion(Long.parseLong(idQuestion));
	}
	
	@GET
	@Produces("application/json")
	@Path("/create")
	public synchronized String creerQuestion(@QueryParam("contenuQuestion") String contenuQuestion, @QueryParam("categorie") String libelleCategorie) throws Exception {
		
		QuestionDto questionDto = new QuestionDto(contenuQuestion.trim());
		
		CategorieDto categorieDto = new CategorieDto(libelleCategorie.trim());
		questionDto.setCategorie(categorieDto);
		
		Question question = new Question();
		
		question = (Question) pcService.creerQuestion(utils.convertQuestionDtoToQuestion(questionDto));

		questionDto = QrhWsUtils.convertQuestionToQuestionDto(question);
		
		return gson.toJson(questionDto, QuestionDto.class);
		
	}
	
	@GET
	@Path("/update")
	@Transactional
	public synchronized String updateQuestion(@QueryParam("idQuestion") String idQuestion,  @QueryParam("contenuQuestion") String contenuQuestion, @QueryParam("categorie") String libelleCategorie) throws Exception {
		
		Question question = (Question) crudService.read(Integer.parseInt(idQuestion), Question.class.getCanonicalName());
		question.setContenuQuestion(contenuQuestion.trim());
		question.setCategorie((Categorie) crudService.read(libelleCategorie, Categorie.class.getCanonicalName()));
		
		question = pcService.modifierQuestion(question);
		
		QuestionDto questionDto = QrhWsUtils.convertQuestionToQuestionDto(question);
		
		
		return gson.toJson(questionDto, QuestionDto.class);
	}

	
	@GET
	@Path("/import")
	public String importQuestions(String filePath) throws IOException,
			JDOMException {
		try {
			File file = new File(filePath);
			InputStream inputStream = new FileInputStream(file);

			List<Question> questions = QrhUtil.importQuestions(inputStream);
			for (Question question : questions) {
				Categorie categorie = (Categorie) crudService.read(question
						.getCategorie().getLibelleCategorie(), Categorie.class
						.getCanonicalName());
				question.setCategorie(categorie);

				List<Reponse> reps = question.getReponsesEventuelles();
				List<Reponse> reponses = new ArrayList<Reponse>(reps.size());
				for (Reponse reponse : reps) {
					reponse = (Reponse) crudService.create(reponse);
					reponses.add(reponse);
				}
				question.setReponsesEventuelles(reponses);

				reps = question.getReponsesCorrectes();
				List<Reponse> repos = new ArrayList<Reponse>(reps.size());
				for (Reponse reponse : reps) {
					reponse = QrhUtil.findReponse(reponses,
							reponse.getContenuReponse());
					repos.add(reponse);
				}
				question.setReponsesCorrectes(repos);

				crudService.create(question);
			}
			return "SUCCESS";
		} catch (Exception ex) {
			return "FAILURE";
		}
	}
	
	@GET
	@Path("/getQuestionById")
	@Transactional
	public synchronized String getQuestionById(@QueryParam("idQuestion")String idQuestion){
		
		Question question = (Question) crudService.read(Integer.parseInt(idQuestion), Question.class.getCanonicalName());
		QuestionDto questionDto = QrhWsUtils.convertQuestionToQuestionDto(question);
		
		return gson.toJson(questionDto, QuestionDto.class); 
	}
	
	@POST
	@Path("/addReponsesEventuelles")
	@Transactional
	public synchronized String addReponsesEventuelles(String json) throws Exception{
		
		String idQuestion = getIdQuestionFromJson(json);
		List<String> idReponses = getIdReponseCollectionFromJson(json);
		
		Question question = pcService.addReponsesEventuellesToQuestion(idQuestion, idReponses);
		if(null != question){
			QuestionDto questionDto = QrhWsUtils.convertQuestionToQuestionDto(question);
			return gson.toJson(questionDto, QuestionDto.class);
		}
		
		return null;
	}
	
	@POST
	@Path("/addReponsesCorrectes")
	@Transactional
	public synchronized String addReponsesCorrectes(String json) throws Exception {

		String idQuestion = getIdQuestionFromJson(json);
		List<String> idReponses = getIdReponseCollectionFromJson(json);
		
		Question question = pcService.addReponsesCorrectesToQuestion(idQuestion, idReponses);
		
		if(null != question){
			QuestionDto questionDto = QrhWsUtils.convertQuestionToQuestionDto(question);
			return gson.toJson(questionDto, QuestionDto.class);
		}
		
		return null;
	}
	
	private List<String> getIdReponseCollectionFromJson(String json) {
		JsonParser parser = new JsonParser();
		JsonObject jObject = (JsonObject)parser.parse(json);
		
		JsonElement jIdReponses =  jObject.get("idReponses");
		
		String s = jIdReponses.getAsString();
		JsonArray jaIdReponses = (JsonArray) parser.parse(s);
		
		List<String> idReponses = new ArrayList<String>();
		
		for(int i = 0; i < jaIdReponses.size(); i++){
			idReponses.add(jaIdReponses.get(i).getAsString());
		}
		
		return idReponses;
	}

	private String getIdQuestionFromJson(String json) {
		
		JsonParser parser = new JsonParser();
		JsonObject jObject = (JsonObject)parser.parse(json);
		
		JsonElement jIdQuestion =  jObject.get("idQuestion");
		return jIdQuestion.getAsString();
	}
}
